home *** CD-ROM | disk | FTP | other *** search
/ Garbo / Garbo.cdr / mac / source / music4c.sit / Music4C Folder / Sources Folder / Music4CFile.c < prev    next >
Text File  |  1990-09-09  |  23KB  |  859 lines

  1. /*
  2. * ⌐ Graeme Gerrard 1990
  3. * Faculty of Music, University of Melbourne
  4. * Parkville Victoria 3052 Australia.
  5. *
  6. * ARPANET: grae@murdu.ucs.unimelb.edu.au
  7. * telephone: (613) 344 4127, Fax: (613) 344 5346
  8. */
  9.  
  10.  
  11. #include    "Music4C.h"
  12. #include "Music4C_Prototype.h"
  13. /*#include    <unix.h>*/
  14. Boolean    OpenSFWrite(void);
  15. Boolean    SetSFDir(Str255, long *);
  16. Boolean    GetSFDir(Str255 *);
  17. Boolean    CloseSF(void);
  18. Boolean    FullFileName(StringPtr, StringPtr, short, long);
  19. Boolean    updateSFResFile(void);
  20. void    Finish(void);
  21. Boolean    SFVolDir(short, short *, long *);
  22. Boolean    doSD2Resources(void);
  23. OSErr    FullToFolder(StringPtr, short *, long *);
  24. void    FixUp(void);
  25. extern void  SaveMusic4C_Prefs(void);
  26. extern    void    ClosePass3Input(void);
  27.  
  28. Boolean    ScoreFileIsOpen;
  29. Boolean    SoundFileIsOpen;
  30. Boolean    ReportFileIsOpen;
  31.  
  32. #define    SAMPLE_SIZE_RES        1000
  33. #define    SAMPLE_RATE_RES        1001
  34. #define    SAMPLE_CHANNELS_RES    1002
  35.  
  36.  
  37. SFReply        SoundFileReply;
  38. SFReply        ScoreFileReply;
  39. Str255        SoundFileName;
  40. ioParam        myIOParmBlk;
  41. int            sfResFileRefNum;
  42. WDPBRec        myWDParamBlk;
  43. FileParam        fPB;
  44. long            SampleRate;
  45. extern        OSErr    theErr;
  46. Str255        theMess1, theMess2;
  47. int            rfilevRefNum;
  48.  
  49.  
  50.  
  51.  
  52. Boolean
  53. OpenSFWrite()
  54. {
  55.  
  56.     SFTypeList    types;
  57.     Point        where;
  58.     int            AppResFile;
  59.     extern        long            StartUpDirID;
  60.     extern        long            SoundFileDirID;
  61.     extern        int            SFoutputType;
  62.     extern        int            SFSaveVRef;
  63.     extern        int            SFvRefNum;
  64.     extern        Str255        SFDirectoryName;
  65.     int    c;
  66.     short    volume;
  67.     long    folder;
  68.     short wd;
  69.     extern            int            nchnls;        /* number of output channels */
  70.     
  71.     if ( SFDirectoryName[0] != NIL ) {
  72.         if ( !SetSFDir(SFDirectoryName, &SoundFileDirID) ) {
  73.             CurDirStore = StartUpDirID;
  74.             return(FALSE);
  75.         }
  76.     }
  77.     PstringCopy((char *)SoundFileName, (char *)ScoreFileReply.fName);
  78.     PtoCstr((char *)SoundFileName);
  79.     c = strcspn((char *)SoundFileName,".");
  80.     switch(SFoutputType) {
  81.         case    INT16:
  82.             strcpy((char *)SoundFileName+c, ".INT16");
  83.             break;
  84.         case    AIFF:
  85.             strcpy((char *)SoundFileName+c, ".AIF");
  86.             break;
  87.         case    SD:
  88.             strcpy((char *)SoundFileName+c, ".SD");
  89.             break;
  90.         case    FLOAT:
  91.             strcpy((char *)SoundFileName+c, ".FLOAT");
  92.             break;
  93.     }
  94.     
  95.     CtoPstr((char *)SoundFileName);
  96.     
  97.     SetPt(&where, 100, 100);
  98.     SFPutFile(where, "\pSound File name:", &SoundFileName, NIL, &SoundFileReply);
  99.     if(!SoundFileReply.good)
  100.         return(FALSE);
  101.         
  102.     GetSFDir(&SFDirectoryName);
  103.     /* we now have the directory where the sound file is to be created,
  104.     save it in the Music4C_Prefs file */
  105.     SaveMusic4C_Prefs();
  106.     SetSFDir(SFDirectoryName, &SoundFileDirID);
  107.  
  108.     PstringCopy((char *)SoundFileName, (char *)SoundFileReply.fName);
  109.     myIOParmBlk.ioNamePtr = (StringPtr)SoundFileName;
  110.     myIOParmBlk.ioVRefNum = SoundFileReply.vRefNum;
  111.     myIOParmBlk.ioVersNum = SoundFileReply.version;
  112.  
  113.     if ( (theErr = PBCreate(&myIOParmBlk, FALSE)) != noErr ) {
  114.         if ( theErr == dupFNErr ) {    /* set logical EOF's to zero */
  115.             myIOParmBlk.ioPermssn = fsWrPerm;
  116.             myIOParmBlk.ioMisc = (Ptr)NIL;
  117.             theErr = PBOpen(&myIOParmBlk, FALSE);
  118.             if ( theErr != noErr ) {
  119.                 PstringCopy((char *)theMess1, "\pError opening sound file:");
  120.                 OSError(theMess1, SoundFileName, theErr);
  121.                 CurDirStore = StartUpDirID;
  122.                 return(FALSE);
  123.             }
  124.             myIOParmBlk.ioMisc = (Ptr)1;
  125.             theErr = PBSetEOF(&myIOParmBlk, FALSE);
  126.             if ( theErr != noErr ) {
  127.                 PstringCopy((char *)theMess1, "\pError setting EOF for sound file:");
  128.                 OSError(theMess1, SoundFileName, theErr);
  129.                 CurDirStore = StartUpDirID;
  130.                 return(FALSE);
  131.             }
  132.             theErr = PBClose(&myIOParmBlk, FALSE);
  133.             if ( theErr != noErr ) {
  134.                 PstringCopy((char *)theMess1, "\pError while setting EOF for sound file:");
  135.                 OSError(theMess1, SoundFileName, theErr);
  136.                 CurDirStore = StartUpDirID;
  137.                 return(FALSE);
  138.             }
  139.         
  140.             /* do resource fork */
  141.             myIOParmBlk.ioMisc = (Ptr)NIL;
  142.             theErr = PBOpenRF(&myIOParmBlk, FALSE);
  143.             if ( theErr != noErr ) {
  144.                 PstringCopy((char *)theMess1, "\pError opening sound file resource fork:");
  145.                 OSError(theMess1, SoundFileName, theErr);
  146.                 CurDirStore = StartUpDirID;
  147.                 return(FALSE);
  148.             }
  149.             theErr = PBSetEOF(&myIOParmBlk, FALSE);
  150.             if ( theErr != noErr ) {
  151.                 PstringCopy((char *)theMess1, "\pError setting EOF for sound file resource fork:");
  152.                 OSError(theMess1, SoundFileName, theErr);
  153.                 CurDirStore = StartUpDirID;
  154.                 return(FALSE);
  155.             }
  156.             /* close resource fork */
  157.             theErr = PBClose(&myIOParmBlk, FALSE);
  158.             if ( theErr != noErr ) {
  159.                 PstringCopy((char *)theMess1, "\pError while setting EOF for sound file:");
  160.                 OSError(theMess1, SoundFileName, theErr);
  161.                 CurDirStore = StartUpDirID;
  162.                 return(FALSE);
  163.             }
  164.             
  165.         }
  166.         else { /* error other than dupFNerr */
  167.             PstringCopy((char *)theMess1, "\pOpenSFWrite Error creating file:");
  168.                 OSError(theMess1, SoundFileName, theErr);
  169.             CurDirStore = StartUpDirID;
  170.             return(FALSE);
  171.         }
  172.     }
  173.     else { /* new files only */
  174.     }
  175.  
  176.  
  177.     fPB.ioCompletion = (ProcPtr)NIL;
  178.     fPB.ioNamePtr = myIOParmBlk.ioNamePtr;
  179.     fPB.ioVRefNum = myIOParmBlk.ioVRefNum;
  180.     fPB.ioFVersNum = myIOParmBlk.ioVersNum;
  181.     fPB.ioFDirIndex = NIL;
  182.     theErr = PBGetFInfo(&fPB, FALSE);
  183.     if ( theErr != noErr ) {
  184.         PstringCopy((char *)theMess1, "\pOpenSFWrite Error getting PBGetFInfo while opening file:");
  185.                 OSError(theMess1, SoundFileName, theErr);
  186.         CurDirStore = StartUpDirID;
  187.         return(FALSE);
  188.     }
  189.     
  190.     /* set creator */
  191.     fPB.ioFlFndrInfo.fdCreator = 'MU4C';
  192.     switch(SFoutputType) {
  193.         case    INT16:
  194.             fPB.ioFlFndrInfo.fdType = 'IL16';
  195.             break;
  196.         case    AIFF:
  197.             fPB.ioFlFndrInfo.fdType = 'AIFF';
  198.             break;
  199.         case    SD:
  200.             fPB.ioFlFndrInfo.fdType = 'SFIL';
  201.             fPB.ioFlFndrInfo.fdCreator = 'XFER';
  202.             break;
  203.         case    FLOAT:
  204.             fPB.ioFlFndrInfo.fdType = 'TEXT';
  205.             break;
  206.     }
  207.  
  208.     fPB.ioFlFndrInfo.fdFlags = NIL;
  209.     theErr = PBSetFInfo(&fPB, FALSE);
  210.     if ( theErr != noErr ) {
  211.         PstringCopy((char *)theMess1, "\pOpenSFWrite Error setting PBGetFInfo while opening file:");
  212.                 OSError(theMess1, SoundFileName, theErr);
  213.         CurDirStore = StartUpDirID;
  214.         return(FALSE);
  215.     }
  216.     PBFlushVol(&fPB, FALSE);
  217.     
  218.     /* now open it */
  219.     myIOParmBlk.ioPermssn = fsWrPerm;
  220.     myIOParmBlk.ioMisc = (Ptr)NIL;
  221.     if ( (theErr = PBOpen(&myIOParmBlk, FALSE)) != noErr ) {
  222.         PstringCopy((char *)theMess1, "\pOpenSFWrite Error opening file:");
  223.                 OSError(theMess1, SoundFileName, theErr);
  224.         CurDirStore = StartUpDirID;
  225.         return(FALSE);
  226.     }
  227.     return(TRUE);
  228. }
  229.  
  230. Boolean    CloseSF()
  231. {
  232.     extern        int            nchnls;        /* number of output channels */
  233.     if ( (theErr = PBClose(&myIOParmBlk, FALSE)) != noErr ) { 
  234.         PstringCopy((char *)theMess1, "\pError closing Sound File:");
  235.         OSError(theMess1, SoundFileName, theErr);
  236.         return(FALSE);
  237.     }
  238.     
  239.     /* if SD2 file fix file type */
  240.     if ( SFoutputType == SD && nchnls > 1 ) {
  241.         fPB.ioFlFndrInfo.fdType = 'Sd2f';
  242.         fPB.ioFlFndrInfo.fdCreator = 'Sd2a';
  243.         fPB.ioFlFndrInfo.fdFlags = NIL;
  244.         theErr = PBSetFInfo(&fPB, FALSE);
  245.     }
  246.     fPB.ioCompletion = (ProcPtr)NIL;
  247.     fPB.ioNamePtr = myIOParmBlk.ioNamePtr;
  248.     fPB.ioVRefNum = myIOParmBlk.ioVRefNum;
  249.     fPB.ioFVersNum = myIOParmBlk.ioVersNum;
  250.     fPB.ioFDirIndex = NIL;
  251.     if ( (theErr =     PBFlushVol(&fPB, FALSE)) != noErr ) { 
  252.         PstringCopy((char *)theMess1, "\pError returned from PBFlushVol for sample file's volume:");
  253.         OSError(theMess1, NIL, theErr);
  254.         return(FALSE);
  255.     }
  256.     return(TRUE);
  257. }
  258.  
  259.  
  260.  
  261. Boolean    SetSFDir(DirName, theDirID)
  262.     Str255        DirName;
  263.     long        *theDirID;
  264. {
  265.     extern        int            SFSaveVRef;
  266.     extern        int            ReportFileRefNum;
  267.     Str255        aString;
  268.     
  269.     
  270.     PstringCopy((char *)aString, (char *)DirName);
  271.     myWDParamBlk.ioNamePtr = (StringPtr)aString;
  272.     myWDParamBlk.ioCompletion = NIL;
  273.     myWDParamBlk.ioVRefNum = 0;
  274.     myWDParamBlk.ioWDDirID = NIL;
  275.  
  276.     if ( (theErr = PBHSetVol(&myWDParamBlk, FALSE)) != noErr ) {
  277.     }
  278.     
  279.     PBHGetVol(&myWDParamBlk, FALSE);
  280.  
  281.     *theDirID = myWDParamBlk.ioWDDirID;
  282.     CurDirStore = *theDirID;
  283.     
  284.     SFSaveVRef = myWDParamBlk.ioVRefNum;
  285.     SFSaveDisk = -1 * SFSaveVRef;
  286.     return(TRUE);
  287. }
  288.  
  289.  
  290.  
  291. Boolean    GetSFDir(DirName)
  292.     Str255    *DirName;
  293. {
  294.     Str255        myStr;
  295.     WDPBRec        myWDParamBlk;
  296.     DirInfo        myCatInfoBlk;
  297.     
  298.     myCatInfoBlk.ioCompletion = NIL;
  299.     myCatInfoBlk.ioVRefNum = -SFSaveDisk;
  300.     myCatInfoBlk.ioDrDirID = CurDirStore;
  301.     myCatInfoBlk.ioFDirIndex = -1;
  302.     myCatInfoBlk.ioNamePtr = (StringPtr)myStr;
  303.     if ( (theErr = PBGetCatInfo(&myCatInfoBlk, FALSE)) != noErr ) {
  304.         PstringCopy((char *)theMess1, "\pPBGetCatInfo Error:");
  305.         OSError(theMess1, myCatInfoBlk.ioNamePtr, theErr);
  306.         return(FALSE);
  307.     }
  308.     
  309.     PstringCopy((char *)DirName, (char *)myStr);
  310.     PstringCat((char *)DirName, "\p:");
  311.     
  312.     while (myCatInfoBlk.ioDrDirID != 2 ) {
  313.         myCatInfoBlk.ioDrDirID = myCatInfoBlk.ioDrParID;
  314.         if ( (theErr = PBGetCatInfo(&myCatInfoBlk, FALSE)) != noErr ) {
  315.             PstringCopy((char *)theMess1, "\pPBGetCatInfo error:");
  316.             OSError(theMess1, myCatInfoBlk.ioNamePtr, theErr);
  317.             return(FALSE);
  318.         }
  319.         PstringCat((char *)myStr, "\p:");
  320.         PstringCat((char *)myStr, (char *)DirName);
  321.         PstringCopy((char *)DirName, (char *)myStr);
  322.     }
  323.     CurDirStore = myCatInfoBlk.ioDrDirID;
  324.     
  325.     return(TRUE);
  326. }
  327.  
  328.  
  329.  
  330. Boolean    OpenScoreFile()
  331. {
  332.     SFTypeList    types;
  333.     Point    where;
  334.     extern    Str255    ScoreDirectoryName;
  335.     extern    Str255    sfile;
  336.     Str255    tail;
  337.     short    volume;
  338.     long    dirID;
  339.     extern    Str255    StartDirName;
  340.     extern    int        scoreRefNum;
  341.     
  342.     
  343.     SetPt(&where, 100, 100);
  344.     SFGetFile(where, NIL, NIL, -1, NIL, NIL, &ScoreFileReply);
  345.     if(!ScoreFileReply.good)
  346.         return(FALSE);
  347.  
  348. /* get the name of the score folder name */
  349.     StartDirName[0] = 0;
  350.     tail[0] = 0;
  351.     volume = 0;
  352.     dirID = NIL;
  353.     FullFileName(StartDirName, tail, volume, dirID);
  354.  
  355.     scoreRefNum = 0;
  356.     PstringCopy((char *)sfile, (char *)ScoreFileReply.fName);
  357.     theErr = FSOpen(sfile, ScoreFileReply.vRefNum, &scoreRefNum);
  358.     if (theErr != noErr) {
  359.         PstringCopy((char *)theMess1, "\pError opening score file:");
  360.         OSError(theMess1, ScoreFileReply.fName, theErr);
  361.         return(FALSE);
  362.     }
  363.     return(TRUE);
  364. }
  365.  
  366.  
  367. void    CleanUp(errFlag)
  368.     Boolean    errFlag;
  369. {
  370.     extern        int    rfilevRefNum;
  371.     extern        Str255    rfile;
  372.     extern    Boolean        CreateSoundFile;
  373.     extern    Str255        p2tmp;
  374.     int i;
  375.  
  376.     if ( ScoreFileIsOpen ) {
  377.         theErr = FSClose(scoreRefNum);
  378.         ScoreFileIsOpen = FALSE;
  379.     }
  380.     if ( ReportFileIsOpen ) {
  381.         theErr = FSClose(ReportFileRefNum);
  382.         if (errFlag)
  383.             theErr = FSDelete(rfile, rfilevRefNum);
  384.         ReportFileIsOpen = FALSE;
  385.     }
  386.     if ( SoundFileIsOpen ) {
  387.         if (!errFlag)    /* don't update resource if we cancelled out */
  388.             updateSFResFile(); 
  389.         theErr = PBClose(&myIOParmBlk, FALSE);
  390.         SoundFileIsOpen = FALSE;
  391.         if (errFlag)
  392.             theErr = PBDelete(&myIOParmBlk, FALSE);
  393.     }
  394.     FixUp();    /* resets startup directory */
  395. }
  396.  
  397.  
  398.  
  399. typedef    struct {
  400.     int        nstrings;
  401.     unsigned    char        theStrings[256];
  402. } ResDatum;
  403.  
  404. Boolean    updateSFResFile()
  405. {    
  406.     ResDatum            **newSfRes;
  407.     unsigned    char        *strptr;
  408.     Str255            myString;
  409.     StringHandle    myStringHandle1, myStringHandle2, myStringHandle3;
  410.     long            SampleRate;
  411.     extern            int                AppResFile;
  412.     extern            int            nchnls;        /* number of output channels */
  413.     extern            double        srate;        /* sampling rate */
  414.     extern            float            MaxSample;
  415.     extern            float            MinSample;
  416.     extern            int            SFoutputType;
  417.     int    i;
  418.     
  419.     
  420.     
  421.     SampleRate = (long)srate;
  422.     CurDirStore = SoundFileDirID;
  423.  
  424.     myWDParamBlk.ioCompletion = NIL;
  425.     myWDParamBlk.ioNamePtr = NIL;
  426.  
  427.     if ( (theErr = PBOpenWD(&myWDParamBlk, FALSE)) != noErr ) {
  428.         PstringCopy((char *)theMess1, "\pUpdateResFile - PBOpenWD error:");
  429.         OSError(theMess1, myWDParamBlk.ioNamePtr, theErr);
  430.         return(FALSE);
  431.     }
  432.     
  433.     /* open the resource fork */
  434.     CreateResFile(SoundFileName);
  435.     if ( ( theErr = ResError()) != noErr ) {
  436.         PstringCopy((char *)theMess1, "\pupdateSFResFile CreateResFile error:");
  437.             OSError(theMess1, SoundFileName, theErr);
  438.         theErr = PBCloseWD(&myWDParamBlk, FALSE);
  439.         CurDirStore = StartUpDirID;
  440. /*            return(FALSE);*/
  441.     }
  442.         
  443.     sfResFileRefNum = OpenResFile(SoundFileName);
  444.     if ( ( theErr = ResError()) != noErr ) {
  445.         PstringCopy((char *)theMess1, "\pupdateSFResFile: OpenResFile error:");
  446.         OSError(theMess1, SoundFileName, theErr);
  447.         theErr = PBCloseWD(&myWDParamBlk, FALSE);
  448.         CurDirStore = StartUpDirID;
  449.         return(FALSE);
  450.     }
  451.  
  452.     newSfRes = (ResDatum **) NewHandle((long)sizeof(ResDatum));
  453.     HLock(newSfRes);
  454.     
  455.     (**newSfRes).nstrings = 5;
  456.  
  457.     strptr = &((*newSfRes)->theStrings[0]);
  458.     
  459.     switch(SFoutputType) {
  460.         case    INT16:
  461.             PstringCopy((char *)strptr, "\pINT16");
  462.             strptr += (*strptr) + 1;
  463.             break;
  464.         case    AIFF:
  465.             PstringCopy((char *)strptr, "\pAIFF");
  466.             strptr += (*strptr) + 1;
  467.             break;
  468.         case    SD:
  469.             if (nchnls > 1 ) {
  470.                 PstringCopy((char *)strptr, "\pSD2");
  471.                 doSD2Resources();
  472.             }
  473.             else
  474.                 PstringCopy((char *)strptr, "\pSD1");
  475.             strptr += (*strptr) + 1;
  476.             break;
  477.         case    FLOAT:
  478.             PstringCopy((char *)strptr, "\pFLOAT");
  479.             strptr += (*strptr) + 1;
  480.             break;
  481.     }
  482.  
  483.         
  484.     NumToString((long)nchnls, &myString);
  485.     PstringCopy((char *)strptr, (char *)myString);
  486.     strptr += (*strptr) + 1;
  487.  
  488.     NumToString(SampleRate, &myString);
  489.     PstringCopy((char *)strptr, (char *)myString);
  490.     strptr += (*strptr) + 1;
  491.     
  492.     sprintf((char *)myString, "%lf", (double)MaxSample);
  493.     CtoPstr((char *)myString);
  494.     PstringCopy((char *)strptr, (char *)myString);
  495.     strptr += (*strptr) + 1;
  496.     
  497.     sprintf((char *)myString, "%lf", (double)MinSample);
  498.     CtoPstr((char *)myString);
  499.     PstringCopy((char *)strptr, (char *)myString);
  500.     
  501.     
  502.     AddResource(newSfRes, 'STR#', 1000, "\pSF params");
  503.     if ((theErr = ResError()) != noErr) {
  504.         PstringCopy((char *)theMess1, "\pAddResource error in function: updateSFResFile():");
  505.                 OSError(theMess1, NIL, theErr);
  506.         HUnlock(newSfRes);
  507.         DisposHandle(newSfRes);
  508.         theErr = PBCloseWD(&myWDParamBlk, FALSE);
  509.         UseResFile(AppResFile);
  510.         CurDirStore = StartUpDirID;
  511.         return(FALSE);
  512.     }
  513.     ChangedResource(newSfRes);
  514.     if ( (theErr = ResError()) != noErr ) {
  515.         PstringCopy((char *)theMess1, "\pChangedResource error in function: updateSFResFile():");
  516.         OSError(theMess1, SoundFileName, theErr);
  517.         theErr = PBCloseWD(&myWDParamBlk, FALSE);
  518.         CurDirStore = StartUpDirID;
  519.         return(FALSE);
  520.     }
  521.     WriteResource(newSfRes);
  522.     if ( (theErr = ResError()) != noErr ) {
  523.         PstringCopy((char *)theMess1, "\pWriteResource error in function: updateSFResFile():");
  524.         OSError(theMess1, SoundFileName, theErr);
  525.         theErr = PBCloseWD(&myWDParamBlk, FALSE);
  526.         CurDirStore = StartUpDirID;
  527.         return(FALSE);
  528.     }
  529.     
  530.     CloseResFile(sfResFileRefNum);
  531.     if ( (theErr = ResError()) != noErr ) {
  532.         PstringCopy((char *)theMess1, "\pCloseResFile error in function: updateSFResFile():");
  533.         OSError(theMess1, SoundFileName, theErr);
  534.         theErr = PBCloseWD(&myWDParamBlk, FALSE);
  535.         CurDirStore = StartUpDirID;
  536.         return(FALSE);
  537.     }
  538.     HUnlock(newSfRes);
  539.     DisposHandle(newSfRes);
  540.     UseResFile(AppResFile);
  541.     if ( (theErr = ResError()) != noErr ) {
  542.         PstringCopy((char *)theMess1, "\pUseResFile error in function: updateSFResFile():");
  543.         OSError(theMess1, SoundFileName, theErr);
  544.         theErr = PBCloseWD(&myWDParamBlk, FALSE);
  545.         CurDirStore = StartUpDirID;
  546.         return(FALSE);
  547.     }
  548.     CloseSF();
  549.     theErr = PBCloseWD(&myWDParamBlk, FALSE);
  550.     CurDirStore = StartUpDirID;
  551.     return(TRUE);
  552. }
  553.  
  554.  
  555. /*-------------------------------------------------------------------------------*/
  556.  
  557. Boolean    SFVolDir(short wd, short *volume, long *folder)
  558. {
  559.     WDPBRec pb;
  560.     unsigned char name[72];
  561.     
  562.     pb.ioNamePtr = (StringPtr)name;
  563.     pb.ioVRefNum = wd;
  564.     pb.ioWDIndex = 0;
  565.     pb.ioWDProcID = 0;
  566.     pb.ioWDVRefNum = 0;
  567.     PBGetWDInfo(&pb, false);
  568.     if (pb.ioResult) return pb.ioResult;
  569.     *volume = pb.ioWDVRefNum;
  570.     *folder = pb.ioWDDirID;
  571.     return (noErr);
  572. }
  573.  
  574.  
  575. /*
  576. FullFileName should be passed an empty string in tail if you just want
  577. the name of a folder.
  578. */
  579. Boolean    FullFileName(StringPtr outname, StringPtr tail, short volume, long dirID)
  580. {
  581.     StringHandle name;
  582.     Str255 text, volname;
  583.     HVolumeParam hvp;
  584.     CInfoPBRec di;
  585.     long size;
  586.     short err;
  587.  
  588.     /* extract the volume name */
  589.     hvp.ioNamePtr = volname;
  590.     hvp.ioVRefNum = volume;
  591.     hvp.ioVolIndex = 0;
  592.     PBHGetVInfo((HParmBlkPtr)&hvp, false);
  593.     if (hvp.ioVSigWord == 0xd2d7) {
  594.         outname[0] = 0;
  595.         return (noErr);
  596.     }
  597.  
  598.     /* create and initialize the name handle */
  599.     if (tail) {
  600.         if (err = PtrToHand(tail + 1, &name, tail[0]))
  601.             return (err);
  602.         size = tail[0];
  603.     }
  604.     else {
  605.         if ((name = (StringHandle)NewHandle(NIL)) == 0)
  606.             return (MemError());
  607.         size = 0;
  608.     }
  609.  
  610.     /* now start extracting the dirs and prepending them to
  611.      * the handle
  612.      */
  613.     for ( ; dirID != 2; dirID = di.dirInfo.ioDrParID) {
  614.         text[0] = 0;
  615.         di.dirInfo.ioNamePtr = text;
  616.         di.dirInfo.ioVRefNum = volume;
  617.         di.dirInfo.ioFDirIndex = -1;
  618.         di.dirInfo.ioDrDirID = dirID;
  619.         PBGetCatInfo(&di, false);
  620.         text[++text[0]] = ':';
  621.         SetHandleSize(name, size += text[0]);
  622.         BlockMove((Ptr)*name, (Ptr)(*name) + text[0], size - text[0]);
  623.         BlockMove((Ptr)text + 1, (Ptr)*name, text[0]);
  624.     }
  625.  
  626.     /* prepend the volume name onto the handle */
  627.     volname[++volname[0]] = ':';
  628.     SetHandleSize(name, size += volname[0]);
  629.     BlockMove((Ptr)*name, (Ptr)(*name) + volname[0], size - volname[0]);
  630.     BlockMove((Ptr)volname + 1, (Ptr)*name, volname[0]);
  631.  
  632.     /* copy and delete the handle */
  633.     if (size > 255) {
  634.         DisposHandle(name);
  635.         SysBeep(12);
  636.         outname[0] = 0;
  637.         return err;
  638.     }
  639.     outname[0] = size;
  640.     BlockMove((Ptr)*name, (Ptr)outname + 1, size);
  641.     DisposHandle(name);
  642.     return (noErr);
  643. }
  644.  
  645.  
  646. /* And on the theory that you might want to convert the name back some day,
  647. here's a routine I use for that.  Notice that it will actually create the
  648. directory if it doesn't exist now.  If this isn't what you want, throw
  649. away the error recovery code.
  650. */
  651.  
  652. OSErr    FullToFolder(StringPtr name, short *volume, long *folder)
  653. {
  654.     CInfoPBRec dirInfo;
  655.     HVolumeParam hvp;
  656.     short i;
  657.     
  658.     dirInfo.dirInfo.ioNamePtr = name;
  659.     dirInfo.dirInfo.ioDrDirID = 0;
  660.     dirInfo.dirInfo.ioVRefNum = 0;
  661.     dirInfo.dirInfo.ioFDirIndex = 0;
  662.     if (PBGetCatInfo (&dirInfo, 0) == noErr) {
  663.         if (dirInfo.dirInfo.ioFlAttrib & 0x10) {
  664.             *folder = dirInfo.dirInfo.ioDrDirID;
  665.             hvp.ioNamePtr = name;
  666.             for (i = 0; i < name[0]; i++)
  667.                 if (name[i+1] == ':') {
  668.                     name[0] = i + 1; break;
  669.                 }
  670.             hvp.ioVolIndex = -1;
  671.             hvp.ioVRefNum = 0;
  672.             PBHGetVInfo ((HParmBlkPtr)&hvp, 0);
  673.             *volume = hvp.ioVRefNum;
  674.         }
  675.         else {
  676.             *volume = 0;
  677.             *folder = 0;
  678.             return (-1);
  679.         }
  680.     }
  681.     else if (dirInfo.dirInfo.ioResult == fnfErr || dirInfo.dirInfo.ioResult == dirNFErr) {
  682.          dirInfo.dirInfo.ioNamePtr = (StringPtr)name;
  683.         dirInfo.dirInfo.ioDrDirID = 0;
  684.         dirInfo.dirInfo.ioVRefNum = 0;
  685.         if (PBDirCreate((HParmBlkPtr)&dirInfo, false) == noErr) {
  686.             *volume = dirInfo.dirInfo.ioVRefNum;
  687.             *folder = dirInfo.dirInfo.ioDrDirID;
  688.         }
  689.         else {
  690.             *volume = 0;
  691.             *folder = 0;
  692.             return (dirInfo.dirInfo.ioResult);
  693.         }
  694.     }
  695.     else {
  696.         *volume = 0;
  697.         *folder = 0;
  698.         return (dirInfo.dirInfo.ioResult);
  699.     }
  700.     return (noErr);
  701. }
  702.  
  703. Boolean    OpenReportFile(ReportFileRefNum)
  704.     int        *ReportFileRefNum;
  705. {
  706.     SFTypeList    types;
  707.     Point        where;
  708.     extern        Str255    sfile;
  709.     extern        Str255    rfile;
  710.     SFReply        ReportFileReply;
  711.     extern        int    rfilevRefNum;
  712.     
  713.     PstringCopy((char *)rfile, (char *)sfile);
  714.     PstringCat((char *)rfile, "\pReport");
  715.     SetPt(&where, 100, 100);
  716.     types[0] = 'TEXT';
  717.     SFPutFile(where, "\pReport File name:", &rfile, NIL, &ReportFileReply);
  718.     if(!ReportFileReply.good)
  719.         return(FALSE);
  720.     PstringCopy((char *)rfile, (char *)ReportFileReply.fName);
  721.     if ( (theErr = Create(rfile, ReportFileReply.vRefNum, 'MU4C', 'TEXT')) != noErr ) {
  722.         if ( theErr == dupFNErr ) {
  723.             rfilevRefNum = ReportFileReply.vRefNum;
  724.             theErr = FSDelete(rfile, rfilevRefNum);
  725.             if ( (theErr = Create(rfile, ReportFileReply.vRefNum, 'MU4C', 'TEXT')) != noErr ) {
  726.                 PstringCopy((char *)theMess1, "\pError creating report file:");
  727.                 OSError(theMess1, NIL, theErr);
  728.                 FixUp();
  729.                 Finish();
  730.             }
  731.         }
  732.         else {
  733.             PstringCopy((char *)theMess1, "\pError opening report file:");
  734.             OSError(theMess1, NIL, theErr);
  735.             FixUp();
  736.             Finish();
  737.         }
  738.  
  739.     }
  740.     theErr = FSOpen(rfile, ReportFileReply.vRefNum, ReportFileRefNum);
  741.     if ( theErr != noErr ) {
  742.         PstringCopy((char *)theMess1, "\pError opening report file:");
  743.         OSError(theMess1, NIL, theErr);
  744.         FixUp();
  745.         Finish();
  746.     }
  747.  
  748.     return(TRUE);
  749. }
  750.  
  751.  
  752.  
  753. void    FixUp()
  754. {
  755.     if ( StartDirName[0] != NIL ) {
  756.         SetSFDir(StartDirName, &StartUpDirID);
  757.     }
  758. }
  759. void    Finish()
  760. {
  761.     InitCursor();
  762.     ExitToShell();
  763. }
  764.  
  765.  
  766.  
  767. Boolean    doSD2Resources()
  768. {
  769.     register        i;
  770.     StringHandle    myStringHandle1, myStringHandle2, myStringHandle3;
  771.     Str255            myString;
  772.  
  773.     myStringHandle1 = (StringHandle)NewHandle(sizeof(StringHandle));
  774.     i = sprintf((char *)myString, "%d", (int)nchnls);
  775.     CtoPstr((char *)myString);
  776.     SetString(myStringHandle1, myString);
  777.     HLock((Handle)myStringHandle1);
  778.     AddResource((Handle)myStringHandle1, 'STR ', SAMPLE_CHANNELS_RES, "\pchannels");
  779.     HUnlock((Handle)myStringHandle1);
  780.     
  781.     ChangedResource((Handle)myStringHandle1);
  782.     if ( (theErr = ResError()) != noErr ) {
  783.         PstringCopy((char *)theMess1, "\pChangedResource error in updateNewSFResFile()");
  784.         OSError(theMess1, SoundFileName, theErr);
  785.         HUnlock((Handle)myStringHandle1);
  786.         DisposHandle((Handle)myStringHandle1);
  787.         return(FALSE);
  788.     }
  789.     WriteResource((Handle)myStringHandle1);
  790.     if ( (theErr = ResError()) != noErr ) {
  791.         PstringCopy((char *)theMess1, "\pWriteResource error in updateNewSFResFile()");
  792.         OSError(theMess1, SoundFileName, theErr);
  793.         HUnlock((Handle)myStringHandle1);
  794.         DisposHandle((Handle)myStringHandle1);
  795.         return(FALSE);
  796.     }
  797.  
  798.     myStringHandle2 = (StringHandle)NewHandle(sizeof(StringHandle));
  799.     i = sprintf((char *)myString, "%ld", (long)SampleRate);
  800.     CtoPstr((char *)myString);
  801.     SetString(myStringHandle2, myString);
  802.     HLock((Handle)myStringHandle2);
  803.     AddResource((Handle)myStringHandle2, 'STR ', SAMPLE_RATE_RES, "\psample-rate");
  804.     HUnlock((Handle)myStringHandle2);
  805.  
  806.     ChangedResource((Handle)myStringHandle2);
  807.     if ( (theErr = ResError()) != noErr ) {
  808.         PstringCopy((char *)theMess1, "\pChangedResource error in updateNewSFResFile()");
  809.         OSError(theMess1, SoundFileName, theErr);
  810.         HUnlock((Handle)myStringHandle2);
  811.         DisposHandle((Handle)myStringHandle2);
  812.         return(FALSE);
  813.     }
  814.     WriteResource((Handle)myStringHandle2);
  815.     if ( (theErr = ResError()) != noErr ) {
  816.         PstringCopy((char *)theMess1, "\pWriteResource error in updateNewSFResFile()");
  817.         OSError(theMess1, SoundFileName, theErr);
  818.         HUnlock((Handle)myStringHandle2);
  819.         DisposHandle((Handle)myStringHandle2);
  820.         return(FALSE);
  821.     }
  822.  
  823.  
  824.  
  825.     myStringHandle3 = (StringHandle)NewHandle(sizeof(StringHandle));
  826.     SetString(myStringHandle3, "\p2");
  827.     HLock((Handle)myStringHandle3);
  828.     AddResource((Handle)myStringHandle3, 'STR ', SAMPLE_SIZE_RES, "\psample-size");
  829.     HUnlock((Handle)myStringHandle3);
  830.  
  831.     if ((theErr = ResError()) != noErr) {
  832.         PstringCopy((char *)theMess1, "\pAddResource error in updateNewSFResFile()");
  833.         OSError(theMess1, SoundFileName, theErr);
  834.         HUnlock((Handle)myStringHandle3);
  835.         DisposHandle((Handle)myStringHandle3);
  836.         return(FALSE);
  837.     }
  838.     ChangedResource((Handle)myStringHandle3);
  839.     if ( (theErr = ResError()) != noErr ) {
  840.         PstringCopy((char *)theMess1, "\pChangedResource error in updateNewSFResFile()");
  841.         OSError(theMess1, SoundFileName, theErr);
  842.         HUnlock((Handle)myStringHandle3);
  843.         DisposHandle((Handle)myStringHandle3);
  844.         return(FALSE);
  845.     }
  846.     WriteResource((Handle)myStringHandle3);
  847.     if ( (theErr = ResError()) != noErr ) {
  848.         PstringCopy((char *)theMess1, "\pWriteResource error in updateNewSFResFile()");
  849.         OSError(theMess1, SoundFileName, theErr);
  850.         HUnlock((Handle)myStringHandle3);
  851.         DisposHandle((Handle)myStringHandle3);
  852.         return(FALSE);
  853.     }
  854.     HUnlock((Handle)myStringHandle3);
  855.     DisposHandle((Handle)myStringHandle1);
  856.     DisposHandle((Handle)myStringHandle2);
  857.     DisposHandle((Handle)myStringHandle3);
  858.     
  859. }